function Map (battleHandle) {
	// Special map element
	var D_CLIFF_Y_OFFSET = 18;
	var L_CLIFF_X_OFFSET = 30;
	var R_CLIFF_X_OFFSET = 30;
	var U_CLIFF_Y_OFFSET = 33;
	
	// Ground tile array. 
	// Ground[i][j] = ground tile at x = i, y = j
	this.m_ground = new Array();
	
	// Init all ground tile to snow
	for (var i=0; i<MAP_SIZE_W; i++) {
		this.m_ground[i] = new Array();
		for (var j=0; j<MAP_SIZE_H; j++) {
			this.m_ground[i][j] = MAP_TILE_SNOW;
		}
	}
	
	// Object tile array
	this.m_object = new Array();
	
	// Init all object tile to empty
	for (var i=0; i<MAP_SIZE_W; i++) {
		this.m_object[i] = new Array();
		for (var j=0; j<MAP_SIZE_H; j++) {
			this.m_object[i][j] = 0;
		}
	}
	
	// Start to load the image required
	var snowImageHandle = g_graphicEngine.LoadImage("Data/ActionPhase/Map/Ground.jpg");
	var waterImageHandle;
	if (PLATFORM > PLATFORM_DESKTOP)
		waterImageHandle = g_graphicEngine.LoadImage("Data/ActionPhase/Map/Water.jpg");
	else
		waterImageHandle = g_graphicEngine.LoadImage("Data/ActionPhase/Map/WaterAnimated.jpg");
		
	var DCliffImageHandle = g_graphicEngine.LoadImage("Data/ActionPhase/Map/DCliff.jpg");
	var LCliffImageHandle = g_graphicEngine.LoadImage("Data/ActionPhase/Map/LCliff.png");
	var RCliffImageHandle = g_graphicEngine.LoadImage("Data/ActionPhase/Map/RCliff.png");
	var UCliffImageHandle = g_graphicEngine.LoadImage("Data/ActionPhase/Map/UCliff.png");
	
	
	// FOR BROWSERS
	var WATER_LOOP_FRAME_LENGTH = 60;
	var NUMBER_OF_WATER_TILE = 30;
	var tempWaterLoopCount = 0;
	var tempWaterLoopIndex = 0;
	
	// FOR TIZEN
	var bufferW = MAP_SIZE_W * MAP_TILE_SIZE;
	var bufferH = MAP_SIZE_H * MAP_TILE_SIZE;
	var bufferCanvas = document.createElement("canvas");
	var bufferContext = bufferCanvas.getContext("2d");
	bufferCanvas.width  = bufferW;
	bufferCanvas.height = bufferH;
	var alreadyRendered = false;
	
	
	
	
	this.LoadMapFromArray = function (array, reverse) {
		for (var i=0; i<MAP_SIZE_W; i++) {
			this.m_ground[i] = new Array();
			for (var j=0; j<MAP_SIZE_H; j++) {
				if (reverse) this.m_ground[i][j] = array[j][i];
				else         this.m_ground[i][j] = array[i][j];
			}
		}
	}
	
	
	
	
	this.Update = function () {
		if (PLATFORM == PLATFORM_DESKTOP) {
			tempWaterLoopCount += g_deltaTime;
			if (tempWaterLoopCount > WATER_LOOP_FRAME_LENGTH) {
				tempWaterLoopCount -= WATER_LOOP_FRAME_LENGTH;
				if (tempWaterLoopCount > WATER_LOOP_FRAME_LENGTH) {
					tempWaterLoopCount = 0;
				}
				
				tempWaterLoopIndex += 1;
				if (tempWaterLoopIndex >= NUMBER_OF_WATER_TILE) {
					tempWaterLoopIndex = 0;
				}
			}
		}
	}
	
	this.Draw = function () {
		if (PLATFORM > PLATFORM_DESKTOP) {
			if (alreadyRendered == false) {
				this.Render();
			}
			g_graphicEngine.CopyCanvas (g_context, bufferCanvas, 0, 0, bufferW, bufferH, BATTLE_OFFSET_X, BATTLE_OFFSET_Y, bufferW, bufferH);
		}
		else {
			for (var i=0; i<MAP_SIZE_W; i++) {
				for (var j=0; j<MAP_SIZE_H; j++) {
					if (this.m_ground[i][j] == MAP_TILE_SNOW) {
						g_graphicEngine.Draw (g_context, snowImageHandle, MAP_TILE_SIZE * i, MAP_TILE_SIZE * j, MAP_TILE_SIZE, MAP_TILE_SIZE, MAP_TILE_SIZE * i + BATTLE_OFFSET_X, MAP_TILE_SIZE * j + BATTLE_OFFSET_Y, MAP_TILE_SIZE, MAP_TILE_SIZE);
					}
					else if (this.m_ground[i][j] == MAP_TILE_WATER) {
						var tempX = tempWaterLoopIndex % 6;
						var tempY = (tempWaterLoopIndex / 6) >> 0;
						
						
						g_graphicEngine.Draw (g_context, waterImageHandle, MAP_TILE_SIZE * tempX, MAP_TILE_SIZE * tempY, MAP_TILE_SIZE, MAP_TILE_SIZE, MAP_TILE_SIZE * i + BATTLE_OFFSET_X, MAP_TILE_SIZE * j + BATTLE_OFFSET_Y, MAP_TILE_SIZE, MAP_TILE_SIZE);
						
						if (j > 0 && this.m_ground[i][j-1] == 1) {
							g_graphicEngine.Draw (g_context, DCliffImageHandle, 0, 0, MAP_TILE_SIZE, MAP_TILE_SIZE, MAP_TILE_SIZE * i + BATTLE_OFFSET_X, MAP_TILE_SIZE * j - D_CLIFF_Y_OFFSET + BATTLE_OFFSET_Y, MAP_TILE_SIZE, MAP_TILE_SIZE);
							g_graphicEngine.Draw (g_context, waterImageHandle, MAP_TILE_SIZE * tempX, MAP_TILE_SIZE * tempY, MAP_TILE_SIZE, MAP_TILE_SIZE, MAP_TILE_SIZE * i + BATTLE_OFFSET_X, MAP_TILE_SIZE * j + BATTLE_OFFSET_Y, MAP_TILE_SIZE, MAP_TILE_SIZE, 0.5);
						}
						
						if (i > 0 && this.m_ground[i-1][j] == 1) {
							g_graphicEngine.Draw (g_context, LCliffImageHandle, 0, 0, MAP_TILE_SIZE, MAP_TILE_SIZE, MAP_TILE_SIZE * (i-1) + L_CLIFF_X_OFFSET + BATTLE_OFFSET_X, MAP_TILE_SIZE * j + BATTLE_OFFSET_Y, MAP_TILE_SIZE, MAP_TILE_SIZE);
						}
						if (i < MAP_SIZE_W - 1 && this.m_ground[i+1][j] == 1) {
							g_graphicEngine.Draw (g_context, RCliffImageHandle, 0, 0, MAP_TILE_SIZE, MAP_TILE_SIZE, MAP_TILE_SIZE * i + L_CLIFF_X_OFFSET + BATTLE_OFFSET_X, MAP_TILE_SIZE * j + BATTLE_OFFSET_Y, MAP_TILE_SIZE, MAP_TILE_SIZE);
						}
						if (j < MAP_SIZE_H - 1 && this.m_ground[i][j+1] == 1) {
							g_graphicEngine.Draw (g_context, UCliffImageHandle, 0, 0, MAP_TILE_SIZE, MAP_TILE_SIZE, MAP_TILE_SIZE * i + BATTLE_OFFSET_X, MAP_TILE_SIZE * j + U_CLIFF_Y_OFFSET + BATTLE_OFFSET_Y, MAP_TILE_SIZE, MAP_TILE_SIZE);
						}
					}
				}
			}
		}
	}
	
	
	this.Render = function () {
		if (PLATFORM > PLATFORM_DESKTOP) {
			g_graphicEngine.ClearCanvas (bufferContext);
			
			for (var i=0; i<MAP_SIZE_W; i++) {
				for (var j=0; j<MAP_SIZE_H; j++) {
					if (this.m_ground[i][j] == MAP_TILE_SNOW) {
						g_graphicEngine.Draw (bufferContext, snowImageHandle, MAP_TILE_SIZE * i, MAP_TILE_SIZE * j, MAP_TILE_SIZE, MAP_TILE_SIZE, MAP_TILE_SIZE * i, MAP_TILE_SIZE * j, MAP_TILE_SIZE, MAP_TILE_SIZE);
					}
					else if (this.m_ground[i][j] == MAP_TILE_WATER) {
						g_graphicEngine.Draw (bufferContext, waterImageHandle, 0, 0, MAP_TILE_SIZE, MAP_TILE_SIZE, MAP_TILE_SIZE * i, MAP_TILE_SIZE * j, MAP_TILE_SIZE, MAP_TILE_SIZE);
						
						if (j > 0 && this.m_ground[i][j-1] == 1) {
							g_graphicEngine.Draw (bufferContext, DCliffImageHandle, 0, 0, MAP_TILE_SIZE, MAP_TILE_SIZE, MAP_TILE_SIZE * i, MAP_TILE_SIZE * j - D_CLIFF_Y_OFFSET, MAP_TILE_SIZE, MAP_TILE_SIZE);
							g_graphicEngine.Draw (bufferContext, waterImageHandle, 0, 0, MAP_TILE_SIZE, MAP_TILE_SIZE, MAP_TILE_SIZE * i, MAP_TILE_SIZE * j, MAP_TILE_SIZE, MAP_TILE_SIZE, 0.5);
						}
						
						if (i > 0 && this.m_ground[i-1][j] == 1) {
							g_graphicEngine.Draw (bufferContext, LCliffImageHandle, 0, 0, MAP_TILE_SIZE, MAP_TILE_SIZE, MAP_TILE_SIZE * (i-1) + L_CLIFF_X_OFFSET, MAP_TILE_SIZE * j, MAP_TILE_SIZE, MAP_TILE_SIZE);
						}
						if (i < MAP_SIZE_W - 1 && this.m_ground[i+1][j] == 1) {
							g_graphicEngine.Draw (bufferContext, RCliffImageHandle, 0, 0, MAP_TILE_SIZE, MAP_TILE_SIZE, MAP_TILE_SIZE * i + L_CLIFF_X_OFFSET, MAP_TILE_SIZE * j, MAP_TILE_SIZE, MAP_TILE_SIZE);
						}
						if (j < MAP_SIZE_H - 1 && this.m_ground[i][j+1] == 1) {
							g_graphicEngine.Draw (bufferContext, UCliffImageHandle, 0, 0, MAP_TILE_SIZE, MAP_TILE_SIZE, MAP_TILE_SIZE * i, MAP_TILE_SIZE * j + U_CLIFF_Y_OFFSET, MAP_TILE_SIZE, MAP_TILE_SIZE);
						}
					}
				}
			}
			
			alreadyRendered = true;
		}
	}
}